#ifndef AFFICHAGE_H
#   define AFFICHAGE_H

#include "SDL/SDL.h"

#include "carte_zone.h"
#include "base_donnees.h"
#include "etat_bataille.h"
#include "resume_saisie.h"
#include "etat_exploration.h"
#include "tab_regions_accessibles.h"

#include "constantes_et_macros.h"




/**
 * \fn static void remplir_rectangle_surface(surface_jeu* surface,
                                             rectangle_pour_surface* rect,
                                             const Uint32 couleur)
 * \brief Remplit un rectangle avec une couleur sur une surface
 *
 * \param[out] surface La surface concernee
 * \param[in] rect Le rectangle a remplir
 * \param[in] couleur La couleur a utiliser, sur 32 bits
 */
void remplir_rectangle_surface(surface_jeu* surface,
                               rectangle_pour_surface* rect,
                               const Uint32 couleur);



/**
 * \fn void rafraichir_ecran(surface_jeu* ecran)
 * \brief Permet de rafraichir l'affichage d'une surface
 *
 * \param[in,out] ecran L'adresse de la surface a rafraichir
 */
void rafraichir_ecran(surface_jeu* ecran);



/**
 * \fn void afficher_image(surface_jeu* ecran, surface_jeu* image,
                           const unsigned int x,
                           const unsigned int y)
 * \brief Colle l'integralite d'une image a un endroit donne
 *
 * \param[in,out] ecran L'adresse de l'ecran
 * \param[in] image L'adresse de l'image a coller
 * \param[in] x Coordonnee horizontale, en pixels, de
 *              l'endroit ou l'on souhaite afficher l'image
 * \param[in] y Coordonnee verticale, en pixels, de
 *              l'endroit ou l'on souhaite afficher l'image
 */
void afficher_image(surface_jeu* ecran, surface_jeu* image,
                    const unsigned int x,
                    const unsigned int y);



/**
 * \fn void ecrire_sur_surface(surface_jeu* surface,
                               const unsigned int pos_x, const unsigned int pos_y,
                               const char* texte, font* font_a_utiliser,
                               const unsigned char rouge, const unsigned char vert,
                               const unsigned char bleu)
 * \brief Affiche une chaine de caractere donnee sur la surface donnee a
 *        l'endroit donne en utilisant la font donnee dans la couleur donnee
 *
 * \param[in,out] surface La surface sur laquelle on veut ecrire
 * \param[in] pos_x Coordonnee horizontale, en pixels, de l'endroit ou on veut ecrire
 * \param[in] pos_y Coordonnee verticale, en pixels, de l'endroit ou on veut ecrire
 * \param[in] texte La chaine de caracteres a afficher
 * \param[in] font_a_utiliser L'adresse de la font que l'on souhaite utiliser
 * \param[in] rouge Taux de rouge : de 0 a 255 inclus
 * \param[in] vert Taux de vert : de 0 a 255 inclus
 * \param[in] bleu Taux de bleu : de 0 a 255 inclus
 */
void ecrire_sur_surface(surface_jeu* surface,
                        const unsigned int pos_x, const unsigned int pos_y,
                        const char* texte, font* font_a_utiliser,
                        const unsigned char rouge, const unsigned char vert,
                        const unsigned char bleu);



/**
 * \fn surface_jeu* creer_ecran(const unsigned int dim_x, const unsigned int dim_y)
 * \brief cree un ecran de la taille souhaitee avec la bibliotheque graphique utilisee
 *
 * \param[in] dim_x Largeur que l'on souhaite donner a l'ecran
 * \param[in] dim_y Hauteur que l'on souhaite donner a l'ecran
 *
 * Note : la bibliotheque graphique doit avoir ete initialisee avant l'appel de
 * cette fonction.
 */
surface_jeu* creer_ecran(const unsigned int dim_x, const unsigned int dim_y);



/**
 * \fn void detruire_surface(surface_jeu* surface)
 * \brief Libere la memoire allouee pour une surface
 *
 * \param[in] surface L'adresse de la surface a detruire
 */
void detruire_surface(surface_jeu* surface);



/**
 * \fn surface_jeu* charger_image(const char* nom_fichier)
 * \brief Charge une image au format bmp et renvoie un pointeur
 *        vers la surface ainsi generee
 *
 * \param[in] nom_fichier Le nom du fichier a charger
 * \return L'adresse de la surface generee a partir de l'image
 *
 * Cette fonction quitte l'application avec un message d'erreur si
 * le chargement echoue.
 */
surface_jeu* charger_image(const char* nom_fichier);



/**
 * \fn font* ouvrir_font(const char* nom_font, const unsigned char taille,
                         const char silencieux)
 * \brief Ouvre la font en .ttf dont le nom est passe en
 *        argument et la met a une taille donnee
 *
 * \param[in] nom_font Le nom de la font a ouvrir (avec l'extension)
 * \param[in] taille La taille a laquelle on souhaite mettre la font
 * \param[in] silencieux Si VRAI, aucun affichage. Utiliser FAUX sinon
 * \return Un pointeur vers la font ouverte
 */
font* ouvrir_font(const char* nom_font, const unsigned char taille,
                  const char silencieux);



/**
 * \fn void fermer_font(font* font_a_fermer)
 * \brief Ferme une font precedemment ouverte
 *
 * \param[in] font_a_fermer L'adresse de la font a fermer
 */
void fermer_font(font* font_a_fermer);



/**
 * \fn void afficher_bataille(const struct etat_bataille* bataille,
                              const struct etat_partie* partie,
                              const struct carte_zone* carte,
                              const struct resume_saisie* saisie,
                              const unsigned int temps,
                              const struct base_donnees* donnees)
 * \brief Affiche le champ de vision du joueur sur l'ecran lors d'une bataille
 *
 * \param[in] bataille L'adresse de l'etat de la bataille
 * \param[in] partie L'adresse de l'etat de la partie
 * \param[in] carte La carte de la zone
 * \param[in] saisie L'adresse d'un resume des actions entreprises par le joueur
 * \param[in] temps Le temps ecoule depuis le lancement du jeu
 * \param[in] donnees Une base de donnees correctement remplie
 *
 * Note : l'endroit ou apparaitra le champ de vision est defini, en nombre
 * de pixels, par les constantes POSITION_CHAMP_VISION_X et
 * POSITION_CHAMP_VISION_Y.\n
 * Elles font reference au coin superieur gauche du champ de vision.
 */
void afficher_bataille(const struct etat_bataille* bataille,
                       const struct etat_partie* partie,
                       const struct carte_zone* carte,
                       const struct resume_saisie* saisie,
                       const unsigned int temps,
                       const struct base_donnees* donnees);



/**
 * \fn void afficher_carte_region(const struct etat_partie* partie,
                                  const struct etat_exploration* exploration,
                                  struct base_donnees* donnees)
 * \brief Affiche la carte d'une region en indiquant par
 *        la meme occasion l'avancement de l'exploration
 *
 * \param[in] partie L'adresse de l'etat de la partie
 * \param[in] exploration L'adresse de l'etat de l'exploration en cours
 * \param[in] donnees Une base de donnees correctement remplie
 */
void afficher_carte_region(const struct etat_partie* partie,
                           const struct etat_exploration* exploration,
                           struct base_donnees* donnees);



/**
 * \fn void afficher_carte_monde(const struct tab_regions_accessibles* accessibles,
                                 struct base_donnees* donnees)
 * \brief Affiche la carte du monde en indiquant les regions auxquelles le joueur a acces
 *
 * \param[in] accessibles L'adresse d'un tableau de regions accessibles
 * \param[in] donnees L'adresse d'une base de donnees correctement remplie
 */
void afficher_carte_monde(const struct tab_regions_accessibles* accessibles,
                          struct base_donnees* donnees);



/**
 * \fn void afficher_aide(surface_jeu* ecran, font* font_aide)
 * \brief Affiche des explications sur le jeu
 *
 * \param[in,out] ecran L'adresse de l'ecran
 * \param[in] font_aide La font a utiliser pour ecrire les instructions
 */
void afficher_aide(surface_jeu* ecran, font* font_aide);



/* ===== Mode texte (pour menus etc) ===== */

/**
 * \fn void demarrer_texte(void)
 * \brief Lance le mode texte pour afficher des menus
 *
 * \warning Un appel a arreter_texte devra etre fait avant la fin du programme
 */
void demarrer_texte(void);



/**
 * \fn fenetre_texte* ouvrir_fenetre_texte(const unsigned int dim_x,
                                           const unsigned int dim_y,
                                           const unsigned int pos_x,
                                           const unsigned int pos_y)
 * \brief Ouvre une fenetre permettant d'afficher du texte et eventuellement
 *        d'interagir avec le joueur
 *
 * \param[in] dim_x Nombre de colonnes contenues par la fenetre
 * \param[in] dim_y Nombre de lignes contenues par la fenetre
 * \param[in] pos_x Position horizontale de la fenetre
 * \param[in] pos_y Position verticale de la fenetre
 * \return Un pointeur vers la fenetre
 */
fenetre_texte* ouvrir_fenetre_texte(const unsigned int dim_x,
                                    const unsigned int dim_y,
                                    const unsigned int pos_x,
                                    const unsigned int pos_y);



/**
 * \fn void fermer_fenetre_texte(fenetre_texte* fenetre)
 * \brief Ferme une fenetre ouverte avec ouvrir_fenetre_texte
 *
 * \param[in] fenetre L'adresse de la fenetre a fermer
 */
void fermer_fenetre_texte(fenetre_texte* fenetre);



/**
 * \fn void arreter_texte(void)
 * \brief Quitte le mode texte
 */
void arreter_texte(void);



/**
 * \fn void vider_fenetre_texte(fenetre_texte* fenetre)
 * \brief Vide une fenetre de se contenu
 *
 * \param[in,out] fenetre L'adresse de la fenetre a vider
 */
void vider_fenetre_texte(fenetre_texte* fenetre);



/**
 * \fn void afficher_stats_objet(fenetre_texte* fenetre,
                                 unsigned int* pos_y,
                                 const unsigned int id_objet,
                                 const struct base_donnees* donnees)
 * \brief Affiche les caracteristiques d'un
 *        objet en preservant les boites des menus
 *
 * \param[in,out] fenetre L'adresse de la fenetre dans laquelle on veut ecrire
 * \param[in,out] pos_y La position verticale d'ecriture, qui
 *                      sera incrementee a chaque ligne ecrite
 * \param[in] id_objet L'id de l'objet concerne
 * \param[in] donnees L'adresse d'une base de donnees correctement remplie
 */
void afficher_stats_objet(fenetre_texte* fenetre,
                          unsigned int* pos_y,
                          const unsigned int id_objet,
                          const struct base_donnees* donnees);



/**
 * \fn void afficher_titre_fenetre(fenetre_texte* fenetre, const char* titre)
 * \brief Affiche un titre en haut d'une fenetre
 *
 * \param[in,out] fenetre L'adresse de la fenetre concernee
 * \param[in] titre Le titre a afficher
 */
void afficher_titre_fenetre(fenetre_texte* fenetre, const char* titre);



/**
 * \fn void afficher_dans_boite(fenetre_texte* fenetre,
                                unsigned int* pos_y,
                                char* texte)
 * \brief Affiche une chaine de caractere dans une fenetre a une ligne donnee
 *        avec un decalage horizontal de deux caracteres, afin de preserver le
 *        cadre de la fenetre
 *
 * \param[in,out] fenetre L'adresse de la fenetre concernee
 * \param[in,out] pos_y L'adresse du numero de la ligne a laquelle on veut ecrire
 * \param[in] texte La chaine a ecrire
 *
 * \warning Cette fonction incremente le numero de ligne. Ainsi, en cas
 *          d'appels consecutifs, les chaines apparaissent les unes en dessous
 *          des autres.\n
 *          Ne mettez pas de '\\n' dans texte, cela efface la boite !\n
 *          De plus, sachez que cette fonction n'est valable que pour une
 *          ligne et decoupe la chaine si elle est sort de la fenetre.
 */
void afficher_dans_boite(fenetre_texte* fenetre,
                         unsigned int* pos_y,
                         char* texte);



/**
 * \fn void afficher_evolution_stats(fenetre_texte* fenetre, unsigned int* pos_y,
                                     const struct etat_partie* partie,
                                     const unsigned int id_objet,
                                     const char type_objet,
                                     const struct base_donnees* donnees)
 * \brief Affiche l'evolution des statistiques du joueur en lui montrant les
 *        stats temporaires (cad en comptant les stats de l'equipement) qu'il
 *        obtiendrait en equipant un objet donne
 *
 * \param[in,out] fenetre L'adresse de la fenetre dans laquelle
 *                        on veut afficher ces informations
 * \param[in,out] pos_y L'adresse du numero de la ligne a laquelle on veut ecrire
 * \param[in] partie L'adresse de l'etat de la partie
 * \param[in] id_objet L'id de l'objet a "essayer"
 * \param[in] type_objet Le type de l'objet concerne. Sert si id_objet est VIDE
 * \param[in] donnees L'adresse d'une base de donnees correctement remplie
 *
 * \warning Ne pas appeler cette fonction avec un objet utilisable !
 */
void afficher_evolution_stats(fenetre_texte* fenetre, unsigned int* pos_y,
                              const struct etat_partie* partie,
                              const unsigned int id_objet,
                              const char type_objet,
                              const struct base_donnees* donnees);



/**
 * \fn void afficher_quantite(fenetre_texte* fenetre,
                              unsigned int* pos_y,
                              const struct etat_partie* partie,
                              const unsigned int id_objet)
 * \brief Affiche le nombre d'exemplaires d'un
 *        objet donne possedes par le joueur dans une fenetre_texte
 *
 * \param[in,out] fenetre La fenetre concernee
 * \param[in,out] pos_y Position verticale d'affichage
 * \param[in] partie L'adresse de l'etat de la partie
 * \param[in] id_objet L'id de l'objet concerne
 */
void afficher_quantite(fenetre_texte* fenetre,
                       unsigned int* pos_y,
                       const struct etat_partie* partie,
                       const unsigned int id_objet);



/**
 * \fn fenetre_texte* afficher_stats_joueur(const unsigned int x_fenetre,
                                            const unsigned int y_fenetre,
                                            const struct etat_partie* partie,
                                            const struct base_donnees* donnees)
 * \brief Affiche diverses informations sur la partie en cours
 *
 * \param[in] x_fenetre La position horizontale a laquelle va apparaitre la
 *                      fenetre qui montrera les statistiques
 * \param[in] y_fenetre La position verticale a laquelle va apparaitre la
 *                      fenetre qui montrera les statistiques
 * \param[in] partie L'adresse de l'etat de la partie
 * \param[in] donnees L'adresse d'une base de donnees correctement remplie
 * \return Un pointeur vers la fenetre qui contient les statistiques
 *
 * \warning Il est important de recuperer le pointeur renvoye par cette
 *          fonction et de fermer la fenetre de statistiques avec
 *          fermer_fenetre_texte avant de quitter le mode texte !
 */
fenetre_texte* afficher_stats_joueur(const unsigned int x_fenetre,
                                     const unsigned int y_fenetre,
                                     const struct etat_partie* partie,
                                     const struct base_donnees* donnees);




#endif /* AFFICHAGE_H */
